﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.Generic;
using System.Linq;
using System.Diagnostics;
using UIObjects.DragDropInterfaces;

namespace UIObjects.TreeViewInterfaces
{
    public enum TreeNodeImageFormat
    {
        Unknown,
        Png,
        Jpeg
    }

    public enum SpecialPropertyType
    {
        ContextMenu,
        Image,
        Children
    }

    public enum SpecialStockActionMenu
    {
        AddChildNode,
        Cut,
        Copy,
        Paste,
        Edit,
        Search
    }

    [AttributeUsage(AttributeTargets.Field)]
    public class TransferCreationMappingAttribute : Attribute
    {
        public string DisplayText { get; private set; }

        public TransferCreationMappingAttribute(string displayText)
        {
            this.DisplayText = displayText;
        }
    }

    [Flags()]
    public enum TransferCreationMappingType
    {
        [TransferCreationMapping("Copy To")]
        CopyTo = 1,
        [TransferCreationMapping("Move To")]
        MoveTo = 2,
        [TransferCreationMapping("Shortcut To")]
        ShortcutTo = 4,
        [TransferCreationMapping("Create New")]
        CreateNew = 8,
        [TransferCreationMapping("Custom Drop/Paste To")]
        Custom = 16
    }

    public enum QueryBranchType
    {
        If,
        ElseIf,
        Switch,
        SwitchCase,
        SwitchDefault,
        Throw,
        Catch,
        Finally,
        ForEach,
        For,
        Do,
        While,
        Continue,
        Break
    }

    [AttributeUsage(AttributeTargets.Field)]
    public class PropertyTypeAttribute : Attribute
    {
        public string DisplayText { get; private set; }
        public Type PropertyType { get; private set; }
        public bool IsTag { get; private set; }
        public SpecialPropertyType SpecialPropertyType { get; private set; }

        public PropertyTypeAttribute(string displayText, Type propertyType)
        {
            this.DisplayText = displayText;
            this.PropertyType = propertyType;
        }

        public PropertyTypeAttribute(string displayText, Type propertyType, bool isTag)
        {
            this.DisplayText = displayText;
            this.PropertyType = propertyType;
            this.IsTag = isTag;
        }

        public PropertyTypeAttribute(string displayText, SpecialPropertyType specialPropertyType)
        {
            this.DisplayText = displayText;
            this.SpecialPropertyType = specialPropertyType;
        }
    }

    [AttributeUsage(AttributeTargets.Field)]
    public class StockActionMenuAttribute : Attribute
    {
        public string DisplayText { get; private set; }
        public SpecialStockActionMenu? SpecialStockActionMenu { get; private set; }

        public StockActionMenuAttribute(string displayText)
        {
            this.DisplayText = displayText;
        }

        public StockActionMenuAttribute(string displayText, SpecialStockActionMenu specialStockActionMenu)
        {
            this.DisplayText = displayText;
            this.SpecialStockActionMenu = specialStockActionMenu;
        }
    }

    public enum TreeNodePropertyStockBinding
    {
        HardValue,
        Stub,
        Placeholder,
        FromQuery,
        FromAdvancedQuery,
        FromClipboard,
        FromResource,
        FromImageUpload
    }

    public enum TreeNodeMenuItemStockAction
    {
        [StockActionMenu("Add Child Node", SpecialStockActionMenu.AddChildNode)]
        AddChildNode,
        [StockActionMenu("Rename")]
        Rename,
        [StockActionMenu("Delete")]
        Delete,
        [StockActionMenu("Cut", SpecialStockActionMenu.Cut)]
        Cut,
        [StockActionMenu("Copy", SpecialStockActionMenu.Copy)]
        Copy,
        [StockActionMenu("Paste", SpecialStockActionMenu.Paste)]
        Paste,
        [StockActionMenu("Expand")]
        Expand,
        [StockActionMenu("Expand All")]
        ExpandAll,
        [StockActionMenu("Collapse")]
        Collapse,
        [StockActionMenu("Collapse All")]
        CollapseAll,
        [StockActionMenu("Check All")]
        CheckAll,
        [StockActionMenu("Uncheck All")]
        UncheckAll,
        [StockActionMenu("Edit...", SpecialStockActionMenu.Edit)]
        Edit,
        [StockActionMenu("Search...", SpecialStockActionMenu.Search)]
        Search
    }

    [Flags()]
    public enum TreeNodePropertyType
    {
        [PropertyType("Checked Property", typeof(bool))]
        Checked = 1,
        [PropertyType("Context Menu", SpecialPropertyType.ContextMenu)]
        ContextMenu = 2,
        [PropertyType("Text Property", typeof(string))]
        Text = 4,
        [PropertyType("Tool Tip Text Property", typeof(string))]
        ToolTipText = 8,
        [PropertyType("Child Ordinal Property", typeof(int))]
        ChildOrdinal = 16,
        [PropertyType("Level Property", typeof(int))]
        Level = 32,
        [PropertyType("Full Path Property", typeof(string))]
        FullPath = 64,
        [PropertyType("Image Property", SpecialPropertyType.Image)]
        Image = 128,
        [PropertyType("Image Index", typeof(int))]
        ImageIndex = 256,
        [PropertyType("Image Key Property", typeof(object))]
        ImageKey = 512,
        [PropertyType("Is Expanded Property", typeof(bool))]
        IsExpanded = 1024,
        [PropertyType("Is Visible Property", typeof(bool))]
        IsVisible = 2048,
        [PropertyType("Is Children Visible Property", typeof(bool))]
        IsChildrenVisible = 4096,
        [PropertyType("Tag Property", typeof(object), true)]
        Tag = 8192,
        [PropertyType("Has Children Property", typeof(bool))]
        HasChildren = 16384,
        [PropertyType("Children Property", SpecialPropertyType.Children)]
        Children = 16384
    }

    [Flags()]
    public enum TreeNodeOperationType
    {
        PreCopyOperation,
        PreMoveOperation,
        PreLinkOperation,
        PreDeleteOperation,
        PreRenameOperation,
        PreExpandOperation,
        PostCopyOperation,
        PostMoveOperation,
        PostLinkOperation,
        PostDeleteOperation,
        PostRenameOperation,
        PostExpandOperation
    }

    [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]
    public class TreeNodeRootSourceAttribute : System.Attribute
    {
        public TreeNodeRootSourceAttribute(Type BaseClass, string ImageResourceURL)
        {
        }
    }

    [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]
    public class TreeNodeAttribute : System.Attribute
    {
        public TreeNodeAttribute(Type BaseClass, string ImageResourceURL)
        {
        }
    }

    [AttributeUsage(AttributeTargets.Property, AllowMultiple = true, Inherited = true)]
    public class TreeNodePropertyAttribute : System.Attribute
    {
        public TreeNodePropertyAttribute(TreeNodePropertyType type)
        {

        }
    }

    [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
    public class TreeNodeOperationAttribute : System.Attribute
    {
        public TreeNodeOperationAttribute(TreeNodeOperationType operations)
        {
        }
    }

    [AttributeUsage(AttributeTargets.Property, AllowMultiple = true, Inherited = true)]
    public class TreeNodeChildSourceAttribute : System.Attribute
    {
        public TreeNodeChildSourceAttribute(Type ItemType, DragDropEffects allowedEffects, int SourceOrderNumber)
        {
        }

        public TreeNodeChildSourceAttribute(Type ItemType, DragDropEffects allowedEffects, string whereExpression, string orderByExpression, string selectExpression)
        {
        }
    }

    namespace Test
    {
        public class MyEntity
        {
            public string Name { get; set; }

            public MyEntity(string name)
            {
                this.Name = name;
            }

            public static explicit operator MyNode(MyEntity entity)
            {
                var myChildNode = new MyNode(entity);
                return myChildNode;
            }

            public List<MyChildEntity> ChildEntities
            {
                get
                {
                    return new List<MyChildEntity>() { new MyChildEntity("Bob"), new MyChildEntity("Susan"), new MyChildEntity("Jim") };
                }
            }
        }

        public class MyChildEntity
        {
            public string Name { get; set; }

            public MyChildEntity(string name)
            {
                this.Name = name;
            }

            public static explicit operator MyChildNode(MyChildEntity entity)
            {
                var myChildNode = new MyChildNode(entity);
                return myChildNode;
            }
        }

        [TreeNode(typeof(MyChildEntity), "")]
        public class MyChildNode
        {
            public string Name { get; set; }

            private MyChildEntity Entity { get; set; }

            public MyChildNode(MyChildEntity entity)
            {
                this.Entity = entity;
            }
        }

        [TreeNode(typeof(MyEntity), "")]
        public class MyNode
        {
            private MyEntity Entity { get; set; }

            public MyNode(MyEntity entity)
            {
                this.Entity = entity;
            }

            [TreeNodeChildSource(typeof(MyChildEntity), DragDropEffects.Copy | DragDropEffects.Move | DragDropEffects.Link, "", "", "")]
            public IQueryable<MyChildNode> ChildNodes
            {
                get
                {
                    return this.Entity.ChildEntities.AsQueryable().Where(e => e.Name == "Bob").Select<MyChildEntity, MyChildNode>(e => (MyChildNode)e);
                }
            }
        }

        static public class Test
        {
            static void TestNodes()
            {
                var myNode = (MyNode)new MyEntity("Bill");
                var myChildEntities = myNode.ChildNodes;

                foreach (MyChildNode childNode in myChildEntities)
                {
                    Debug.WriteLine(childNode.Name);
                }
            }
        }
    }
}
